#include "test.h"

#include <stdio.h>
#include <stdlib.h>

#include <getopt.h>
#include <unistd.h>

//default seed for srandom()
#define DEFAULT_SEED 111

//default matrix size
#define DEFAULT_SIZE 1024

int main(int argc, char** argv)
{
	int c = 0;
	int seed = DEFAULT_SEED;
	int size = DEFAULT_SIZE;

	//mode, default set as debug mode
	int mode = 'd';

	//useless parameter, for compatibility only
	int option_index = 0;

	//the # of threads/processor used to run this program
	int thread_num = 2;

	//the # of loop used to count the run time
	int loop_num = 1;

	//mode: debug mode, single run mode, parallel run mode
	//seed: set the seed for srandom(), it's optional
	static struct option long_options[] = 
	{
		{"mode", required_argument, 0, 'm'},	
		{"seed", required_argument, 0, 'e'},
		{0, 0, 0, 0}
	};

	//s: set size of matrix
	c = getopt_long(argc, argv, "-s:p:l:", long_options, &option_index);
	while(c != -1)
	{
	
		switch(c)
		{
			//set seed for srandom()
			case 'e':	
			{
				seed = atoi(optarg);	

				break;
			}
			//set matrix size
			case 's':
			{
				size = atoi(optarg);		

				break;
			}
			//select mode for further processing
			case 'm':
			{
				mode = optarg[0];

				break;
			}
			//# of processors used to run the program
			case 'p':
			{
				thread_num = atoi(optarg);	

				break;
			}
			//# of loops used to count the run time
			case 'l':
			{
				loop_num = atoi(optarg);	

				break;
			}
			//exception handling
			case '?':
			{
				abort();

				break;
			}
			default:
			{
				break;
			}
		}

		c = getopt_long(argc, argv, "-s:p:l:", long_options, &option_index);
	}

	switch (mode)
	{
		//parallel mode, invoke the parallel implementation function
		case 'n':
		{
			test_parl_mult(thread_num, size, seed, loop_num, 'n', 0);

			break;
		}
		//advanced mode, invoke the advanced parallen implementation function
		case 'a':
		{
			test_parl_mult(thread_num, size, seed, loop_num, 'a', 0);

			break;
		}
		//debug mode, just invoke the debug function
		case 'd':
		{
			debug_mult(thread_num, size, seed);

			break;
		}
		default:
		{
			break;	
		}
	}


	return EXIT_SUCCESS;
}
